using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;

namespace hoshimiTestBench
{
    public class AI
    {
        public class MapPoint
        {
            public int color;
            public MapField field = null;
            public bool processed = false;
            public bool seen = false;

            public MapPoint(int col)
            {
                color = col;
            }
            public bool Equals(MapPoint other)
            {
                return color == other.color;
            }

            public static MapPoint fromColor(Color c)
            {
                if (c.R == 255 )
                    return new MapPoint(1);
                if (c.G >= 105)
                    return new MapPoint(2);
                if (c.B == 255)
                    return new MapPoint(3);
                if (c.R == 0 && c.B == 0 && c.G == 0)
                    return new MapPoint(0);
                return new MapPoint(5);
            }
        }

        
        public MapPoint[,] map = new MapPoint[200,200];
        public System.Collections.Generic.List<MapField> fields = new List<MapField>();
        public MyBitmap mapBmp;
        
        

        public void MapPointsFromImage(MyBitmap bmp)
        {
            mapBmp = bmp;
            for(int y = 0; y < bmp.Height; y++)
            {
                for (int x = 0; x < bmp.Width; x++)
                {
                    map[x,y] = MapPoint.fromColor(bmp.GetPixel(x, y));
                }
            }
        }


        public unsafe void processMap()
        {
            //Bitmap result = new Bitmap(mapBmp.);
            //placek[,] placki = new placek[200, 200];

            for (int j = 0; j <198; j += 3)
            {
                for (int i = 0; i < 198; i += 3)
                {
                    bool sameColor = true;
                    MapPoint p = map[i, j];
                    if (p.color == 0) continue;
                    int x = 1;
                    int y = 0;

                    while (sameColor && y < 4)
                    {
                        if (!p.Equals(map[i+x,j+y]))
                        {
                            sameColor = false;
                        }
                        else
                        {
                            ++x;
                            y += x / 3;
                            x %= 3;
                        }
                    }
                    if (sameColor)
                    {
                        MapField f = new MapField(i,j);
                        map[i, j].field = f;
                        fields.Add(f);
                        for (int a = -1; a <= 1; a++)
                        {
                            for (int b = -1; b <= 1; b++)
                            {
                                f.points.Add(new Point(i + a, j + b));
                                map[i+a, j+b].field = f;
                                mapBmp.SetPixel(i + a, j + b, Color.YellowGreen);
                            }
                        }
                                                 

                        mapBmp.SetPixel(i, j, Color.Red);
                    }

                }
            }
            return;
        }


        public void connectMapFields()
        {
            foreach(MapField f in fields)
            {
                MapField tmp;
                for (int i = -2; i <= 2; i++)
                {
                    if ((tmp = map[f.x + i, f.y - 2].field) != null && !f.connections.Contains(tmp))
                    {
                        f.connections.Add(tmp);
                        tmp.connections.Add(f);
                    }
                    if ((tmp = map[f.x + i, f.y + 2].field) != null && !f.connections.Contains(tmp))
                    {
                        f.connections.Add(tmp);
                        tmp.connections.Add(f);
                    }
                    if ((tmp = map[f.x - 2, f.y + i].field) != null && !f.connections.Contains(tmp))
                    {
                        f.connections.Add(tmp);
                        tmp.connections.Add(f);
                    }
                    if ((tmp = map[f.x + 2, f.y +i].field) != null && !f.connections.Contains(tmp))
                    {
                        f.connections.Add(tmp);
                        tmp.connections.Add(f);
                    }
                }
            }

            //wyrzucamy te, ktore maja pelon sasiadow
            List<MapField> bin = new List<MapField>();
            foreach (MapField f in fields)
            {
                if (f.connections.Count == 8)
                {
                    bin.Add(f);
                }
            }
            foreach (MapField f in bin)
            {
                foreach (MapField c in f.connections)
                {
                    c.connections.Remove(f);
                }
                fields.Remove(f);
            }
        }

        public void drawGraph()
        {
            //Graphics g = Graphics.FromImage(mapBmp.bitmap);
            foreach (MapField f in fields)
            {
                foreach (MapField c in f.connections)
                {
                    mapBmp.DrawLine(Pens.Coral, f.x, f.y, c.x, c.y);
                }
            }
        }

        public void processMap2()
        {
            for (int j = 0; j< 199; j++)
			{
                for (int i = 0; i < 199; i++)
                {
                        if ( map[i, j].color != map[i + 1, j].color)
                        {
                            map[i + 1, j].processed = true;
                            map[i, j].processed = true;
                        }
                        if (map[i, j].color != map[i, j+1].color)
                        {
                            map[i, j + 1].processed = true;
                            map[i, j].processed = true;
                        }
                    
                }
			}
            for (int j = 0; j < 200; j++)
            {
                for (int i = 0; i < 200; i++)
                {
                    if (map[i, j].processed)
                    {
                        switch (map[i, j].color)
                        {
                            case 1:
                                mapBmp.SetPixel(i, j, Color.FromArgb(255, 100, 100));
                                break;
                            case 2:
                                mapBmp.SetPixel(i, j, Color.FromArgb(100, 255, 100));
                                break;
                            case 3:
                                mapBmp.SetPixel(i, j, Color.FromArgb(100, 100, 255));
                                break;
                            case 0:
                                mapBmp.SetPixel(i, j, Color.FromArgb(50, 50, 50));
                                break;
                        }
                        map[i,j].color += 10;
                    }
                }
            }
        }

        public class Direction
        {
           public static byte[] vals = { 8, 9, 1, 5, 4, 6, 2, 10 };
                                 /*1,2,3,4,5,6,7,8,9,10*/
            static int[] xVals = {1,-1,0,0,1,-1,0,0,1,-1};
            static int[] yVals = {0,0,0,1,1,1,0,-1,-1,-1};
            public static int[] xValsC = { 0,1,1,1,0,-1,-1,-1};
            public static int[] yValsC = { -1,-1,0,1,1,1,0,-1};

            public byte dir = 0;

            public int goX(int a)
            {
                return a + xVals[dir];
                //return a + (((dir & 0x02) != 0) ? (-1) : (((dir & 0x01) != 0) ? 1 : 0));
            }
            public int goY(int a)
            {
                return a + yVals[dir];
                //return a + (((dir & 0x08) != 0) ? (-1) : (((dir & 0x04) != 0) ? 1 : 0));
            }
        }

        public void createLines()
        {
            int x = 0;
            int y = 1; //tak jest latwiej
            //szukamy pierwszego punktu granicznego
            while (y < 200 && !map[x, y].processed)
            {
                x++;
                if (x >= 200)
                {
                    y++;
                    x = 0;
                }
            }


            int i = 0;
            int j = -1;
            int c = 0;
            while (map[x + i, y + j].color != map[x + i, y + j].color)
            {
                c++;
                i = Direction.xValsC[c];
                j = Direction.yValsC[c];
            }
            Direction d = new Direction();
            d.dir = Direction.vals[c];

            x += i;
            y += j;

            
        }
    


    }
}
